/*
	A program that starts a process for both the Java and C messaging portions of Heart of Gold. It also creates and destroys the named pipes the C and Java portions use to communicate. It waits for the Java process to exit then sends the terminate signal to the C messaging processes. 

	by Ryan T. Higgins
	29 APR 04
*/

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/poll.h>
#include "serialio.h"

//starts the java man takes a process id , and two named pipes as arguments
void startJava(pid_t p, char* fifoIn, char* fifoOut){
	//java -cp target/my-app-1.0-SNAPSHOT.jar com.mycompany.app.App
	char* forJava[] = {"java", "-cp", "java_heart-of-gold-1.0-SNAPSHOT.jar",
			"com.heartOfGold.HOGMain", fifoIn , fifoOut, NULL};

	if(p == 0){execvp("java", forJava);}
	return;
}

//starts the process for the messaging from the serial to the Heart of gold application takes a process id and a named pipe
int startSerialtoHOG(pid_t p, char* fifoIn){
	ssize_t wrote, sRed;	
	int fromSerial = -1;
	char* sMessage[1024];
	if(p == 0){
		fromSerial = open(fifoIn, O_WRONLY | O_APPEND, S_IWUSR);
		fprintf(stderr, "C - fromSerial's file descripter is - %d\n", fromSerial);
		for(;;){
			//read it from the serial port
			sRed = read(serial_params.fd, sMessage, 1024);
			//print a status message	
			fprintf(stdout, "C - received from serial and writing to java - %d bytes\n", sRed, sMessage);
			//write it to JavaPipe (fromSerial)
			if(sRed > 0){wrote = write(fromSerial,sMessage , sRed);}
		}
	}
	return 0;
}

//starts the process for messages from java land to serial
int startHOGtoSerial(pid_t p, char* fifoOut){
	ssize_t sWrote, red;
	int toSerial = -1;
	char* message[1024];
	if(p == 0){
		toSerial = open(fifoOut, O_RDONLY, S_IRUSR);
		fprintf(stderr, "C - toSerial's file descripter is - %d\n", toSerial);
		for(;;){
			//read message from Javapipe 
	       		red = read(toSerial, message, 1024);
			if(red > 0){
				//print a status message
				fprintf(stdout, "C received from Java and writing to Serial - %d bytes\n",red, message);
				//write it to the serial port
				sWrote = write(serial_params.fd, message, red);
				
			}
		}

	}
	return 0;

}

int main(int argc, char* argv[])
{
	struct pollfd ufds;
	extern char **environ;
	int* stat;
	pid_t pid1, pid2, pid3;

	open_serial(0);
	setup_serial_params();

	//make the FIFOs
        mkfifo("HOG_In", S_IRWXU);
     	mkfifo("HOG_Out", S_IRWXU);
	// argv array for the exec call

	// fork and start the java
	pid1 = fork();
	startJava(pid1, "HOG_In", "HOG_Out");

	// fork and start the C parts
	pid2 = fork();
	startSerialtoHOG(pid2, "HOG_In");

	pid3 = fork();
	startHOGtoSerial(pid3, "HOG_Out");

	// wait for the Java child to exit
	while(!WIFEXITED(*stat)){waitpid(pid1, stat, 0);}

	// terminate the C pipes
	kill(pid2,SIGTERM);
	kill(pid3,SIGTERM);

	//uh.. for symmetry close serial port
	close_serial();

	// remove FIFOs
	remove("HOG_In");
	remove("HOG_Out");

	return 0;
}
